const request = require('request');
const fs = require('fs');
const path = require('path');
const { to } = require('await-to-js');
const axios = require('axios');

async function chatGPT_d(prompt, cookie, opts, times) {
    times = times || 0;
    opts = {
        bizId: 'engineer',
        bizToken: '3d1c4349-3efc-4c9e-ad8d-7fd0c1a46094',
        nologin: true,
        userId: 'srt',
    }
    return new Promise((resolve, reject) => {
        console.log(prompt);
        axios({
            method: 'post',
            // url: opts.type == 4 ? 'https://agentproxy.top/v0/chat/completions' : 'https://agentproxy.top/v1/chat/completions',
            url: 'https://40-3.chatgptsb.net/v1/chat/completions',
            data: {
                // "model": "gpt-3.5-turbo-16k",
                // "model": "gpt-4-1106-preview",
                // "model": opts.type == 4 ? "gpt-4" : 'gpt-3.5-turbo-16k',
                "model": opts.type == 4 ? "gpt-4-1106-preview" : 'gpt-3.5-turbo-1106',
                "messages": [
                    {
                        "role": "user",
                        "content": prompt.replace(/%/g, '％')
                    }
                ],
                "temperature": 0,
                "stream": false,
                "user": "user",
                // "max_tokens": 1000
            },
            headers: {
                // Authorization: "Bearer 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",
                // Authorization: opts.type == 4 ? "Bearer sk-mwJQOLVM10ae940a3818T3BLbkFJ23720501f3b14a148810" : "Bearer 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",
                Authorization: "Bearer sk-CHOGLbkC00kgT1tLD03a1aB684F74a1c84785dD74470B485",
                Accept: "application/json; charset=utf-8"
            }
        })
        .then((response) => {
            console.log(response.data.choices[0].message.content);
            resolve(response.data.choices[0].message.content);
        })
        .catch((error) => {
            console.error(error);
            console.log('\n\n\n重试第' + times +  '次\n\n\n');
            // reject(error);
            // 重试一次
            if (times == 4) {
                reject(error);
            } else {
                chatGPT_d(prompt, cookie, opts, times + 1).then(data => {
                    resolve(data);
                }).catch(e => {
                    reject(e);
                });
            }
        });
    });
}

// // 读取数据
// function getdata (opts, row) {
//     opts = opts || {};
//     if (!row) {
//         return false;
//     }
//     try {
//         let _t = JSON.parse(fs.readFileSync(process.cwd() + '/userfiles/vocs.js', 'utf8'))[row];
//         for (let i in opts) {
//             _t = _t.filter((ceil) => (ceil[i] == 'undefined' ? 0 : ceil[i]) == opts[i])
//         }
//         return _t;
//     } catch (e) {
//         return [];
//     }
// }

// // 保存数据
// // values = {value: 1, key: 2}
// function savedata (opts, values, row) {
//     if (!row) {
//         return false;
//     }
//     try {
//         let _t = JSON.parse(fs.readFileSync(process.cwd() + '/userfiles/vocs.js', 'utf8'));
//         const _g = _t;

//         // 获得数据
//         for (let i in opts) {
//             _t = _t[row].filter((ceil) => (ceil[i] == 'undefined' ? 0 : ceil[i]) == opts[i]);
//         }
//         if (_t[row]) {}
//         _t[row].forEach((ceil) => ({
//             ...ceil,
//             ...values
//         }));
        
//         fs.writeFileSync(process.cwd()  + '/userfiles/vocs.js', JSON.stringify(_g));
//         return true;
//     } catch (e) {
//         return false;
//     }
// }

// 读取数据函数
function getData(opts, row) {
  const filePath = path.join(process.cwd(), '/userfiles/vocs.js');
  const fileContent = fs.readFileSync(filePath, 'utf8');
  const data = JSON.parse(fileContent);
  const rowData = data[row];
  if (!rowData) {
    throw new Error(`Row ${row} not found`);
  }
  return rowData.filter(item => item.value === opts.value);
}

// 保存数据函数
function saveData(opts, values, row) {
  const filePath = path.join(process.cwd(), '/userfiles/vocs.js');
  const _str = fs.readFileSync(filePath, 'utf8');
  let data = JSON.parse(_str || '{}');
  let rowData = data[row];

  if (!rowData) {
    data[row] = [];
    rowData = data[row];
  }

  if (Object.keys(opts).length === 0) {
    // 新增数据
    rowData.push(values);
  } else {
    // 更新数据
    rowData.forEach(item => {
      if (item.value === opts.value) {
        Object.assign(item, values);
      }
    });
  }

  fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
}

// 根据url，获取评论
// https://sg.xiapibuy.com/-Ready-Stock-Roborock-S8-AI-Robot-Vacuum-HyperForce-6000Pa-Dual-Roller-Brush-UltraSonic-Mopping-Auto-Lift-Up-Mop-Brush-i.126007714.23625845011

// http://127.0.0.1:9988/webstatic/voc-judge?curl=https%3A%2F%2Fsg.xiapibuy.com%2F-Ready-Stock-Roborock-S8-AI-Robot-Vacuum-HyperForce-6000Pa-Dual-Roller-Brush-UltraSonic-Mopping-Auto-Lift-Up-Mop-Brush-i.126007714.23625845011
exports.judge = async function (req, res, next) {
    // 解析url，获得店铺id和商品id
    if (!req.query.curl || !/i\.\d+\.\d+/.test(req.query.curl)) {
        return res.jsonp({ret: 1});
    }
    // 获取店铺id和商品id
    const _sg = req.query.curl.match(/i\.(\d+)\.(\d+)/);
    var item_rating_summary = {};
    var comments = [];

    var id = new Date().getTime();
    // 写入数据
    saveData('', { id, url: req.query.curl, status: 0 }, 'curls');
    
    res.jsonp({ret: 0});

    // 准备去抓数据了
    for (var i = 0; i < 10; i++) {
        const options = {
            url: 'https://sg.xiapibuy.com/api/v2/item/get_ratings?exclude_filter=1&filter=0&filter_size=0&flag=1&fold_filter=0&itemid=' + _sg[2] + '&limit=10&offset=' + (i * 10) + '&relevant_reviews=false&request_source=2&shopid=' + _sg[1] + '&tag_filter=&type=0&variation_filters=',
            method: 'GET',
            json: true,
        };
        const response = await new Promise((resolve, reject) => {
            request(options, (error, response, body) => {
                if (error) {
                    reject(error);
                } else {
                    resolve(body);
                }
            });
        });
        // console.log(i, response.data.ratings.length, response.data.ratings[0].comment);
        item_rating_summary = response.data.item_rating_summary;
        comments = comments.concat(Array.from(response.data.ratings, ceil => ceil.author_username + ' says: ' + ceil.comment + '\n\n'));
    }
    // 写入数据
    saveData({ id }, { status: 1, item_rating_summary, comments }, 'curls');

    // 再去做分析吧
    const [err, data] = await to(Promise.all([chatGPT_d(comments.join('') + `你是一个数据分析师，上面是某个电子产品的所有用户评价。每一个“says”后面是一个用户评价。用户在自由评价的同时，也可能从“Value For Money”，“Best Feature(s)”，“Performance”三个维度，发表自己的看法。

请帮我把里面全部的 NR-Tag(Negative-tag) 和 PR-Tag(Positive-tag) 按照出现的频率次数，罗列出来（NR-Tag和PR-Tag各列出最多前20种即可）。比如：
PR-Tag: good(10), excellence(9), Easy to use(8), Good price(4), Consider expensive(1)....
NR-Tag: bad experience(3), expensive product(1)...

寻找PR-Tag和NR-Tag的范围应该是全文本的，不局限于“Value For Money”，“Best Feature(s)”，“Performance”，还应该在用户自由评论中获取。也不应该局限于确实存在的某个词语，可以读完评论后，判断它对产品的印象，总结出PR-Tag或NR-Tag（比如用户说自己花了10美元，但是感觉不值这个价格，可以总结为: 贵或者性价比不高）`), chatGPT_d(comments.join('') + `你是一个数据分析师，上面是某个电子产品的所有用户评价。每一个“says”后面是一个用户评价。用户在自由评价的同时，也可能从“Value For Money”，“Best Feature(s)”，“Performance”三个维度，发表自己的看法。

请帮我分析上面的所有评论，做一个价格满意度的定量分析。按照每一个标签一行，并配上出现频率的格式输出，如：
物有所值: 218
性价比高/物超所值: 46
便宜: 27
合理: 3
不值得: 1
...
（请注意，上面的标签是举例，实际上的标签，应该根据评论内容来总结）

寻找价格满意度标签的范围应该是全文本的，不局限于“Value For Money”，“Best Feature(s)”，“Performance”，还应该在用户自由评论中获取。也不应该局限于确实存在的某个词语，可以读完评论后，判断它对产品的印象，总结出价格满意度标签（比如用户说自己花了10美元，但是感觉不值这个价格，可以总结为: 不值得）`), chatGPT_d(comments.join('') + `你是一个数据分析师，上面是某个电子产品的所有用户评价。每一个“says”后面是一个用户评价。用户在自由评价的同时，也可能从“Value For Money”，“Best Feature(s)”，“Performance”三个维度，发表自己的看法。

请帮我分析上面的所有评论，做一个总结和建议（包括3部分: 总结、用户建议，未被满足的需求）。
如：
总结：
1. 对于低单价产品，用户会比较关注收货过程，以及使用上的便利，功能完整即可，NR集中在质量相关问题。
2. 性价比，价格对于用户做购买决定的影响较大，并且只要质量没有问题，绝大部分用户都是认为“物有所值”的，并且在“同价位产品中非常具有竞争力”

未被满足的需求：
1. 希望能看到充电盒电量
2. 缺少指示灯
...

用户建议：
1. Listing卖点排列不合理
...

寻找总结和建议全文本的，不局限于“Value For Money”，“Best Feature(s)”，“Performance”，还应该在用户自由评论中获取。也不应该局限于确实存在的某个词语，可以读完评论后，判断它对产品的印象，做总结建议。`)]));

    if (!err) {
        // 结果输出
        saveData({ id }, { status: 2, data }, 'curls');
        console.log(data);
    } else {
        console.log(err);
    }
}

// 获取当前数据
exports.getlist = async function (req, res, next) {
    let list = getData({}, 'curls');
    list = list.map(ceil => {
        ceil.cnum = ceil.comments.length;
        const _item_rating_summary = JSON.parse(JSON.stringify(ceil.item_rating_summary));
        delete ceil.comments;
        delete ceil.item_rating_summary;
        return {
            ...ceil,
            ..._item_rating_summary
        }
    });
    res.jsonp({ret: 0, list });
}

// 获取某一条数据
exports.getone = async function (req, res, next) {
    if (!req.query.id) {
        return res.jsonp({ret: 1});
    }
    const data = getData({id: req.query.id}, 'curls');
    if (data.length == 0) {
        return res.jsonp({ret: 2});
    }
    delete data[0].comments;
    res.jsonp({ret: 0, data: data[0] });
}

// 获取某一条数据
exports.getonecomment = async function (req, res, next) {
    if (!req.query.id) {
        return res.jsonp({ret: 1});
    }
    req.query.pagenum = req.query.pagenum || 1;

    const data = getData({id: req.query.id}, 'curls');
    if (data.length == 0) {
        return res.jsonp({ret: 2});
    }
    // delete data[0].comments;
    res.jsonp({ret: 0, list: data[0].comments.slice(10 * (req.query.pagenum - 1), 10 * req.query.pagenum) });
}

// console.log(getData({value: 1}, 'my'));
// console.log(saveData({value: 1}, {value: 1, a: 11, b: 22, c: 33}, 'my'));
// console.log()